home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / FX / FXAPI.C next >
Encoding:
Text File  |  1998-08-27  |  44.5 KB  |  1,180 lines

  1. /* -*- mode: C; tab-width:8;  -*-
  2.  
  3.              fxapi.c - 3Dfx VooDoo/Mesa interface
  4. */
  5.  
  6. /*
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this library; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  ********************************************************************
  22.  *
  23.  * Function names:
  24.  *  fxMesa....     (The driver API)
  25.  *  fxDD....       (Mesa device driver functions)
  26.  *  fxTM....       (Texture manager functions)
  27.  *  fxSetup....    (Voodoo units setup functions)
  28.  *  fx....         (Internal driver functions)
  29.  *
  30.  * Data type names:
  31.  *  fxMesa....     (Public driver data types)
  32.  *  tfx....        (Private driver data types)
  33.  *
  34.  ********************************************************************
  35.  *
  36.  *
  37.  * V0.29 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  38.  *         - now glGetString(GL_RENDERER) returns more information
  39.  *           about the hardware configuration: "Mesa Glide <version>
  40.  *           <Voodoo_Graphics|Voodoo_Rush|UNKNOWN> <num> CARD/<num> FB/
  41.  *           <num> TM/<num> TMU/<NOSLI|SLI>"
  42.  *           where: <num> CARD is the card used for the current context,
  43.  *           <num> FB is the number of MB for the framebuffer,
  44.  *           <num> TM is the number of MB for the texture memory,
  45.  *           <num> TMU is the number of TMU. You can try to run
  46.  *           Mesa/demos/glinfo in order to have an example of the
  47.  *           output
  48.  *         - fixed a problem of the WGL emulator with the
  49.  *           OpenGL Optimizer 1.1 (thanks to Erwin Coumans for
  50.  *           the bug report)
  51.  *         - fixed some bug in the fxwgl.c code (thanks to  
  52.  *           Peter Pettersson for a patch and a bug report)
  53.  *
  54.  *         Theodore Jump (tjump@cais.com)
  55.  *         - written the SST_DUALHEAD support in the WGL emulator
  56.  *
  57.  *         Daryll Strauss (daryll@harlot.rb.ca.us)
  58.  *         - fixed the Voodoo Rush support for the in window rendering
  59.  *
  60.  * V0.28 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  61.  *         - the only supported multitexture functions are GL_MODULATE
  62.  *           for texture set 0 and GL_MODULATE for texture set 1. In
  63.  *           all other cases, the driver falls back to pure software
  64.  *           rendering
  65.  *         - written the support for the new  GL_EXT_multitexture
  66.  *         - written the DD_MAX_TEXTURE_COORD_SETS support in the
  67.  *           fxDDGetParameteri() function
  68.  *         - the driver falls back to pure software rendering when
  69.  *           texture mapping function is GL_BLEND
  70.  *
  71.  * V0.27 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  72.  *         - inluded in the Mesa-3.0beta5
  73.  *         - written a smal extension (GL_FXMESA_global_texture_lod_bias) in
  74.  *           order to expose the LOD bias related Glide function
  75.  *         - fixed a bug fxDDWriteMonoRGBAPixels()
  76.  *         - the driver is now able to fallback to software rendering in
  77.  *           any case not directly supported by the hardware
  78.  *         - written the support for enabling/disabling dithering
  79.  *         - the in-window-rendering hack now works with any X11 screen
  80.  *           depth
  81.  *         - fixed a problem related to color/depth/alpha buffer clears
  82.  *         - fixed a problem when clearing buffer for a context with the
  83.  *           alpha buffer
  84.  *         - fixed a problem in the fxTMReloadSubMipMapLevel() function,
  85.  *           I have forget a "break;" (thanks to Joe Waters for the bug report)
  86.  *         - fixed a problem in the color format for the in window
  87.  *           rendering hack
  88.  *         - written the fxDDReadRGBAPixels function
  89.  *         - written the fxDDDepthTestPixelsGeneric function
  90.  *         - written the fxDDDepthTestSpanGeneric function
  91.  *         - written the fxDDWriteMonoRGBAPixels function
  92.  *         - written the fxDDWriteRGBAPixels function
  93.  *         - removed the multitexture emulation code for Voodoo board
  94.  *         with only one TMU
  95.  *
  96.  *         Chris Prince <cprince@cs.washington.edu>
  97.  *         - fixed a new bug in the wglUseFontBitmaps code
  98.  *
  99.  *         Ralf Knoesel (rknoesel@Stormfront.com)
  100.  *         - fixed a bug in the wglUseFontBitmaps code
  101.  *
  102.  *         Rune Hasvold (runeh@ifi.uio.no)
  103.  *         - fixed a problem related to the aux usage in the fxBestResolution
  104.  *           function
  105.  *         - fixed the order of pixel formats in the WGL emulator
  106.  *
  107.  *         Fredrik Hubinette (hubbe@hubbe.net)
  108.  *         - the driver shutdown the Glide for most common signals
  109.  *
  110.  * V0.26 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  111.  *         - included in the Mesa-3.0beta4
  112.  *         - fixed a problem related to a my optimization for the Rune's
  113.  *           pixel-span optimization
  114.  *         - fixed a problem related to fxDDSetNearFar() and ctx->ProjectionMatrixType
  115.  *           (thanks to Ben "Ctrl-Alt-Delete" and the Raul Alonso's ssystem)
  116.  *         - fixed a small bug in the Rune's pixel-span optimization
  117.  *         - fixed a problem with GL_CCW (thanks to Curt Olson for and example
  118.  *           of the problem)
  119.  *         - grVertex setup code is now ready for the internal thread support
  120.  *         - fixed a no used optimization with clipped vertices in
  121.  *           grVertex setup code
  122.  *         - fixed a problem in the GL_LIGHT_MODEL_TWO_SIDE support (thanks
  123.  *           to Patrick H. Madden for a complete example of the bug)
  124.  *
  125.  *         Rune Hasvold (runeh@ifi.uio.no)
  126.  *         - highly optimized the driver functions for writing pixel
  127.  *           span (2-3 times faster !)
  128.  *
  129.  *         Axel W. Volley (volley@acm.org) Krauss-Maffei Wehrtechnik
  130.  *         - written the fxDDReadDepthSpanFloat() and fxDDReadDepthSpanInt()
  131.  *           functions
  132.  *
  133.  * V0.25 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  134.  *         - fixed a problem with Voodoo boards with only one TMU
  135.  *         - fixed a bug in the fxMesaCreateContext()
  136.  *         - now the GL_FRONT_AND_BACK works fine also with
  137.  *           the alpha buffer and/or antialiasing
  138.  *         - written the support for GL_FRONT_AND_BACK drawing but
  139.  *           it doesn't works with the alpha buffer and/or antialiasing
  140.  *         - fixed some bug in the Mesa core for glCopyTexSubImage
  141.  *           and glCopyTexImage functions (thanks to Mike Connell
  142.  *           for an example of the problem)
  143.  *         - make some small optimizations in the Mesa core in order
  144.  *           to save same driver call and state change for not very
  145.  *           well written applications
  146.  *         - introduced the NEW_DRVSTATE and make other optimizations
  147.  *           for minimizing state changes
  148.  *         - made a lot of optimizations in order to minimize state
  149.  *           changes
  150.  *         - it isn't more possible to create a context with the
  151.  *           depth buffer and the stancil buffer (it isn't yet supported)
  152.  *         - now the partial support for the Multitexture extension
  153.  *           works with Quake2 for windows
  154.  *         - vertex snap is not longer used for the Voodoo2 (FX_V2
  155.  *           must be defined)
  156.  *         - done a lot of cleanup in the fxsetup.c file
  157.  *         - now the partial support for the Multitexture extension
  158.  *           works with GLQuake for windows
  159.  *
  160.  *         Dieter Nuetzel (nuetzel@kogs.informatik.uni-hamburg.de) University of Hamburg
  161.  *         - fixed a problem in the asm code for Linux of the fxvsetup.c file
  162.  *           highlighted by the binutils-2.8.1.0.29. 'fildw' asm instruction
  163.  *           changed in 'fild'
  164.  *
  165.  *         Kevin Hester (kevinh@glassworks.net)
  166.  *         - written the wglUseFontBitmaps() function in the WGL emulator
  167.  *
  168.  * V0.24 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  169.  *         - now the drive always uses per fragment fog
  170.  *         - written a small optimization in the points drawing function
  171.  *         - written the support for trilinear filtering with 2 TMUs
  172.  *         - written the first partial support for the Multitexture extension.
  173.  *           This task is quite hard because the color combine units work after
  174.  *           the two texture combine units and not before as required by the 
  175.  *           Multitexture extension
  176.  *         - written a workaround in fxBestResolution() in order to solve a
  177.  *           problem with bzflag (it asks for 1x1 window !)
  178.  *         - changed the fxBestResolution() behavior. It now returns the larger
  179.  *           screen resolution supported by the hardware (instead of 640x480)
  180.  *           when it is unable to find an appropriate resolution that is large
  181.  *           enough for the requested size 
  182.  *         - the driver is now able to use also the texture memory attached to
  183.  *           second TMU
  184.  *         - the texture memory manager is now able to work with two TMUs and
  185.  *           store texture maps in the memory attached to TMU0, TMU1 or to split
  186.  *           the mimpmap levels across TMUs in order to support trilinear filtering
  187.  *         - I have bought a Voodoo2 board !
  188.  *         - the amount of frambuffer ram is now doubled when an SLI configuration
  189.  *           is detected
  190.  *         - solved a problem related to the fxDDTexParam() and fxTexInvalidate()
  191.  *           functions (thanks to Rune Hasvold for highlighting the problem)
  192.  *         - done some cleanup in the fxvsetup.c file, written
  193.  *           the FXVSETUP_FUNC macro
  194.  *         - done a lot of cleanup in data types and field names
  195.  *
  196.  *         Rune Hasvold (runeh@ifi.uio.no)
  197.  *         - written the support for a right management of the auxiliary buffer.
  198.  *           You can now use an 800x600 screen without the depth and alpha
  199.  *           buffer
  200.  *         - written the support for a new pixel format (without the depth
  201.  *           and alpha buffer) in the WGL emulator
  202.  *         - fixed a bug in the window version of the GLUT (it was ever asking
  203.  *           for depth buffer)
  204.  *
  205.  * V0.23 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  206.  *         - included in the Mesa-3.0beta2 release
  207.  *         - written the support for the OpenGL 1.2 GL_TEXTURE_BASE_LEVEL
  208.  *           and GL_TEXTURE_MAX_LEVEL
  209.  *         - rewritten several functions for a more clean support of texture
  210.  *           mapping and in order to solve some bug
  211.  *         - the accumulation buffer works (it is  bit slow beacuase it requires
  212.  *           to read/write from/to the Voodoo frame buffer but it works)
  213.  *         - fixed a bug in the fxDDReadRGBASpan driver function (the R and
  214.  *           B channels were read in the wrong order). Thanks to Jason Heym
  215.  *           for highlighting the problem
  216.  *         - written the support for multiple contexts on multiple boards.
  217.  *           you can now use the Mesa/Voodoo with multiple Voodoo Graphics
  218.  *           boards (for example with multiple screens or an HMD)
  219.  *         - the fxBestResolution() now check all available resolutions
  220.  *           and it is able to check the amount of framebuffer memory
  221.  *           before return a resolution
  222.  *         - modified the GLX/X11 driver in order to support all the
  223.  *           resolution available
  224.  *         - changed all function names. They should be now a bit more
  225.  *           readable
  226.  *         - written the Glide grVertex setup code for two TMU or
  227.  *           for Multitexture support with emulationa dn one TMU
  228.  *         - written the support for the new Mesa driver
  229.  *           function GetParametri
  230.  *         - small optimization/clean up in the texbind() function
  231.  *         - fixed a FPU precision problem for glOrtho and texture
  232.  *           mapping (thanks to Antti Juhani Huovilainen for an example
  233.  *           of the problem)
  234.  *         - written some small SGI OpenGL emulation code for the wgl,
  235.  *           the OpenGL Optimizer and Cosmo3D work fine under windows !
  236.  *         - moved the point/line/triangle/quad support in the fxmesa7.c
  237.  *         - fixed a bug in the clear_color_depth() (thanks to Henk Kok
  238.  *           for an example of the problem)
  239.  *         - written a small workaround for Linux GLQuake, it asks
  240.  *           for the alpha buffer and the depth buffer at the some time
  241.  *           (but it never uses the alpha buffer)
  242.  *         - checked the antialiasing points, lines and polygons support.
  243.  *           It works fine
  244.  *         - written the support for standard OpenGL antialiasing using
  245.  *           blending. Lines support works fine (tested with BZflag)
  246.  *           while I have still to check the polygons and points support
  247.  *         - written the support for the alpha buffer. The driver is now
  248.  *           able to use the Voodoo auxiliary buffer as an alpha buffer
  249.  *           instead of a depth buffer. Also all the OpenGL blending
  250.  *           modes are now supported. But you can't request a context
  251.  *           with an alpha buffer AND a depth buffer at the some time
  252.  *           (this is an hardware limitation)
  253.  *         - written the support for switching between the fullscreen
  254.  *           rendering and the in-window-rendering hack on the fly
  255.  *
  256.  *         Rune Hasvold (runeh@ifi.uio.no)
  257.  *         - fixed a bug in the texparam() function
  258.  *
  259.  *         Brian Paul (brianp@elastic.avid.com) Avid Technology
  260.  *         - sources accomodated for the new Mesa 3.0beta1
  261.  *
  262.  * V0.22 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  263.  *         - included with some v0.23 bug fix in the final release
  264.  *           of the Mesa-2.6
  265.  *         - written the support for the MESA_WGL_FX env. var. but
  266.  *           not tested because I have only Voodoo Graphics boards
  267.  *         - fixed a bug in the backface culling code
  268.  *           (thanks to David Farrell for an example of the problem)
  269.  *         - fixed the "Quake2 elevator" bug
  270.  *         - GL_POLYGONS with 3/4 vertices are now drawn as
  271.  *           GL_TRIANLGES/GL_QUADS (a small optimization for GLQuake)
  272.  *         - fixed a bug in fxmesa6.h for GL_LINE_LOOP
  273.  *         - fixed a NearFarStack bug in the Mesa when applications
  274.  *           directly call glLoadMatrix to load a projection matrix 
  275.  *         - done some cleanup in the fxmesa2.c file
  276.  *         - the driver no longer translates the texture maps
  277.  *           when the Mesa internal format and the Voodoo
  278.  *           format are the some (usefull for 1 byte texture maps
  279.  *           where the driver can directly use the Mesa texture
  280.  *           map). Also the amount of used memory is halfed
  281.  *         - fixed a bug for GL_DECAL and GL_RGBA
  282.  *         - fixed a bug in the clear_color_depth()
  283.  *         - tested the v0.22 with the Mesa-2.6beta2. Impressive
  284.  *           performances improvement thanks to the new Josh's
  285.  *           asm code (+10fps in the isosurf demo, +5fps in GLQuake
  286.  *           TIMEREFRESH)
  287.  *         - written a optimized version of the RenderVB Mesa driver
  288.  *           function. The Voodoo driver is now able to upload polygons
  289.  *           in the most common cases at a very good speed. Good
  290.  *           performance improvement for large set of small polygons
  291.  *         - optimized the asm code for setting up the color information
  292.  *           in the Glide grVertex structure
  293.  *         - fixed a bug in the fxmesa2.c asm code (the ClipMask[]
  294.  *           wasn't working)
  295.  *
  296.  *         Josh Vanderhoof (joshv@planet.net)
  297.  *         - removed the flush() function because it isn't required
  298.  *         - limited the maximum number of swapbuffers in the Voodoo
  299.  *           commands FIFO (controlled by the env. var. MESA_FX_SWAP_PENDING)
  300.  *
  301.  *         Holger Kleemiss (holger.kleemiss@metronet.de) STN Atlas Elektronik GmbH
  302.  *         - applied some patch for the Voodoo Rush
  303.  *
  304.  * V0.21 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  305.  *         - the driver is now able to take advantage of the ClipMask[],
  306.  *           ClipOrMask and ClipAndMask information also under Windows
  307.  *         - introduced a new function in the Mesa driver interface
  308.  *           ClearColorAndDepth(). Now the glClear() function is
  309.  *           2 times faster (!) when you have to clear the color buffer
  310.  *           and the depth buffer at some time
  311.  *         - written the first version of the fxRenderVB() driver
  312.  *           function
  313.  *         - optimized the glTexImage() path
  314.  *         - removed the fxMesaTextureUsePalette() support
  315.  *         - fixed a bug in the points support (thanks to David Farrell
  316.  *           for an example of the problem)
  317.  *         - written the optimized path for glSubTexImage(),
  318.  *           introduced a new function in the Mesa driver interface
  319.  *           TexSubImage(...)
  320.  *         - fixed a bug for glColorMask and glDepthMask
  321.  *         - the wbuffer is not more used. The Voodoo driver uses
  322.  *           a standard 16bit zbuffer in all cases. It is more consistent
  323.  *           and now GLQuake and GLQuake2test work also with a GL_ZTRICK 0
  324.  *         - the driver is now able to take advantage of the ClipMask[],
  325.  *           ClipOrMask and ClipAndMask information (under Linux);
  326.  *         - rewritten the setup_fx_units() function, now the texture
  327.  *           mapping support is compliant to the OpenGL specs (GL_BLEND
  328.  *           support is still missing). The LinuxGLQuake console correctly
  329.  *           fade in/out and transparent water of GLQuake2test works fine
  330.  *         - written the support for the env. var. FX_GLIDE_SWAPINTERVAL
  331.  *         - found a bug in the Mesa core. There is a roundup problem for
  332.  *           color values out of the [0.0,1.0] range
  333.  *
  334.  *         Wonko <matt@khm.de>
  335.  *         - fixed a Voodoo Rush related problem in the fxwgl.c
  336.  *
  337.  *         Daryll Strauss <daryll@harlot.rb.ca.us>
  338.  *         - written the scissor test support
  339.  *
  340.  * V0.20 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  341.  *         - written the closetmmanger() function in order to free all the memory
  342.  *           allocated by the Texture Memory Manager (it will be useful
  343.  *           when the support for multiple contexts/boards will be ready)
  344.  *         - now the Voodoo driver runs without printing any information,
  345.  *           define the env. var. MESA_FX_INFO if you want to read some
  346.  *           information about the hardware and some statistic
  347.  *         - written a small workaround for the "GLQuake multiplayer white box bug"
  348.  *           in the setup_fx_units() funxtions. I'm already rewriting
  349.  *           this function because it is the source of nearly all the current
  350.  *           Voodoo driver problems
  351.  *         - fixed the GLQuake texture misalignment problem (the texture
  352.  *           coordinates must be scaled between 0.0 and 256.0 and not
  353.  *           between 0.0 and 255.0)
  354.  *         - written the support for the GL_EXT_shared_texture_palette
  355.  *         - some small change for supporting the automatic building of the
  356.  *           OpenGL32.dll under the Windows platform
  357.  *         - the redefinition of a mipmap level is now a LOT faster. This path
  358.  *           is used by GLQuake for dynamic lighting with some call to glTexSubImage2D()
  359.  *         - the texture memory is now managed a set of 2MB blocks so
  360.  *           texture maps can't be allocated on a 2MB boundary. The new Pure3D
  361.  *           needs this kind of support (and probably any other Voodoo Graphics
  362.  *           board with more than 2MB of texture memory)
  363.  *
  364.  *         Brian Paul (brianp@elastic.avid.com) Avid Technology
  365.  *         - added write_monocolor_span(), fixed bug in write_color_span()
  366.  *         - added test for stenciling in choosepoint/line/triangle functions
  367.  *
  368.  *         Joe Waters (falc@attila.aegistech.com) Aegis
  369.  *         - written the support for the env. var. SST_SCREENREFRESH
  370.  *
  371.  * V0.19 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  372.  *         - written the 3Dfx Global Palette extension for GLQuake
  373.  *         - written the support for the GL_EXT_paletted_texture (it works only with GL_RGBA
  374.  *           palettes and the alpha value is ignored ... this is a limitation of the
  375.  *           the current Glide version and Voodoo hardware)
  376.  *         - fixed the amount of memory allocated for 8bit textures
  377.  *         - merged the under construction v0.19 driver with the Mesa 2.5
  378.  *         - finally written the support for deleting textures
  379.  *         - introduced a new powerful texture memory manager: the texture memory
  380.  *           is used as a cache of the set of all defined texture maps. You can
  381.  *           now define several MB of texture maps also with a 2MB of texture memory
  382.  *           (the texture memory manager will do automatically all the swap out/swap in
  383.  *           work). The new texture memory manager has also
  384.  *           solved a lot of other bugs/no specs compliance/problems
  385.  *           related to the texture memory usage. The texture
  386.  *           manager code is inside the new fxmesa3.c file
  387.  *         - broken the fxmesa.c file in two files (fxmesa1.c and fxmesa2.c)
  388.  *           and done some code cleanup
  389.  *         - now is possible to redefine texture mipmap levels already defined
  390.  *         - fixed a problem with the amount of texture memory allocated for textures
  391.  *           with not all mipmap levels defined
  392.  *         - fixed a small problem with single buffer rendering
  393.  *
  394.  *         Brian Paul (brianp@elastic.avid.com) Avid Technology
  395.  *         - read/write_color_span() now use front/back buffer correctly
  396.  *         - create GLvisual with 5,6,5 bits per pixel, not 8,8,8
  397.  *         - removed a few ^M characters from fxmesa2.c file
  398.  *
  399.  * V0.18 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  400.  *         - the Mesa-2.4beta3 is finally using the driver quads support (the
  401.  *           previous Mesa versions have never taken any advantage from the quads support !)
  402.  *         - tested with the Glide 2.4 for Win
  403.  *         - ported all asm code to Linux
  404.  *         - ported the v0.18 to Linux (without asm code)
  405.  *         - back to Linux !!!
  406.  *         - optimized the SETUP macro (no more vertex snap for points and lines)
  407.  *         - optimized the SETUP macro (added one argument)
  408.  *         - the Mesa/Voodoo is now 20/30% for points, lines and small triangles !
  409.  *         - performance improvement setting VBSIZE to 72 
  410.  *         - the GrVertex texture code is now written in asm
  411.  *         - the GrVertex zbuffer code is now written in asm
  412.  *         - the GrVertex wbuffer code is now written in asm
  413.  *         - the GrVertex gouraud code is now written in asm
  414.  *         - the GrVertex snap code is now written in asm
  415.  *         - changed the 8bit compressed texture maps in 8bit palette texture maps
  416.  *           support (it has the some advantage of compressed texture maps without the
  417.  *           problem of a fixed NCC table for all mipmap levels)
  418.  *         - written the support for 8bit compressed texture maps (but texture maps with
  419.  *           more than one mipmap level aren't working fine)
  420.  *         - finnaly everthing is working fine in MesaQuake !
  421.  *         - fixed a bug in the computation of texture mapping coordinates (I have found
  422.  *           the bug thanks to MesaQuake !)
  423.  *         - written the GL_REPLACE support (mainly for MesaQuake)
  424.  *         - written the support for textures with not all mipmap levels defined
  425.  *         - rewritten all the Texture memory stuff
  426.  *         - written the MesaQuake support (define MESAQUAKE)
  427.  *         - working with a ZBuffer if glOrtho or not int the default glDepthRange,
  428.  *           otherwise working with the WBuffer
  429.  *         written the glDepthRange support
  430.  *
  431.  *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
  432.  *         - written the fxCloseHardware() and the fxQuaryHardware() (mainly
  433.  *           for the VoodooWGL emulator)
  434.  *
  435.  *         Brian Paul (brianp@elastic.avid.com) Avid Technology
  436.  *         - implemented read/write_color_span() so glRead/DrawPixels() works
  437.  *         - now needs Glide 2.3 or later.  Removed GLIDE_FULL_SCREEN and call to grSstOpen()
  438.  *
  439.  * V0.17 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  440.  *         - optimized the bitmap support (66% faster)
  441.  *         - tested with the Mesa 2.3beta2
  442.  *
  443.  *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
  444.  *         - solved a problem with the drawbitmap() and the Voodoo Rush
  445.  *           (GR_ORIGIN_LOWER_LEFT did not work with the Stingray)
  446.  *
  447.  *         Brian Paul (brianp@elastic.avid.com) Avid Technology
  448.  *         - linux stuff
  449.  *         - general code clean-up
  450.  *         - added attribList parameter to fxMesaCreateContext()
  451.  *         - single buffering works now
  452.  *         - VB colors are now GLubytes, removed ColorShift stuff
  453.  *
  454.  *         Paul Metzger
  455.  *         - linux stuff
  456.  *
  457.  * V0.16 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  458.  *         - written the quadfunc support (no performance improvement)
  459.  *         - written the support for the new Mesa 2.3beta1 driver interface (Wow ! It is faaaster)
  460.  *         - rewritten the glBitmap support for the Glide 2.3 (~35% slower !)
  461.  *         - written the glBitmap support for the most common case (fonts)
  462.  *
  463.  *         Jack Palevich
  464.  *         - Glide 2.3 porting
  465.  *
  466.  *         Diego Picciani (d.picciani@novacomp.it) Nova Computer s.r.l.
  467.  *         - extended the fxMesaCreateContext() and fxMesaCreateBestContext()
  468.  *           functions in order to support also the Voodoo Rush
  469.  *         - tested with the Hercules Stingray 128/3D (The rendering in a window works !)
  470.  *
  471.  * V0.15 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  472.  *         - written the GL_LUMINANCE_ALPHA support
  473.  *         - written the GL_ALPHA support
  474.  *         - written the GL_LUMINANCE support
  475.  *         - now SETUP correctly set color for mono color sequences
  476.  *         - written the 9x1,10x1,...,1x9,1x10,... texture map ratio support
  477.  *         - written the no square texture map support
  478.  *         - the fog table is no more rebuilt inside setup_fx_units() each time
  479.  *
  480.  *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
  481.  *         - written (not yet finished: no texture mapping) support for glOrtho
  482.  *         - some change to setup functions
  483.  *         - the fog support is now fully compatible with the standard OpenGL
  484.  *         - rewritten several parts of the driver in order to take
  485.  *           advantage of meshes (40% faster !!!)
  486.  *
  487.  * V0.14 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  488.  *         - now glAlphaFunc() works
  489.  *         - now glDepthMask() works
  490.  *         - solved a mipmap problem when using more than one texture
  491.  *         - moved ti, texid and wscale inside the fxMesaContext (now we can
  492.  *           easy support more ctx and more boards)
  493.  *         - the management of the fxMesaContext was completly broken !
  494.  *         - solved several problems about Alpha and texture Alpha
  495.  *         - 4 (RGBA) texture channels supported
  496.  *         - setting the default color to white
  497.  *
  498.  *         Henri Fousse (arnaud@pobox.oleane.com) Thomson Training & Simulation
  499.  *         - small change to fxMesaCreateContext() and fxMesaMakeCurrent()
  500.  *         - written the fog support
  501.  *         - setting the default clear color to black
  502.  *         - written cleangraphics() for the onexit() function
  503.  *         - written fxMesaCreateBestContext()
  504.  *
  505.  * V0.13 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  506.  *         - now glBlendFunc() works for all glBlendFunc without DST_ALPHA
  507.  *           (because the alpha buffer is not yet implemented) 
  508.  *         - now fxMesaCreateContext() accept resolution and refresh rate
  509.  *         - fixed a bug for texture mapping: the w (alias z) must be set
  510.  *           also without depth buffer
  511.  *         - fixed a bug for texture image with width!=256
  512.  *         - written texparam()
  513.  *         - written all point, line and triangle functions for all possible supported
  514.  *           contexts and the driver is slight faster with points, lines and small triangles
  515.  *         - fixed a small bug in fx/fxmesa.h (glOrtho)
  516.  *
  517.  * V0.12 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  518.  *         - glDepthFunc supported
  519.  *         - introduced a trick to discover the far plane distance
  520.  *           (see fxMesaSetFar and fx/fxmesa.h)
  521.  *         - now the wbuffer works with homogeneous coordinate (and it
  522.  *           doesn't work with a glOrtho projection :)
  523.  *         - solved several problems with homogeneous coordinate and texture mapping
  524.  *         - fixed a bug in all line functions
  525.  *         - fixed a clear framebuffer bug
  526.  *         - solved a display list/teximg problem (but use
  527.  *           glBindTexture: it is several times faster)
  528.  *
  529.  * V0.11 - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  530.  *         - introduced texture mapping support (not yet finished !)
  531.  *         - tested with Mesa2.2b6
  532.  *         - the driver is faster 
  533.  *         - written glFlush/glFinish
  534.  *         - the driver print a lot of info about the Glide lib
  535.  *
  536.  * v0.1  - David Bucciarelli (tech.hmw@plus.it) Humanware s.r.l.
  537.  *         - Initial revision
  538.  *
  539.  */
  540.  
  541. #if defined(FX)
  542.  
  543. #include "fxdrv.h"
  544.  
  545. fxMesaContext fxMesaCurrentCtx=NULL;
  546.  
  547. /*
  548.  * Status of 3Dfx hardware initialization
  549.  */
  550.  
  551. static int glbGlideInitialized=0;
  552. static int glb3DfxPresent=0;
  553. static int glbTotNumCtx=0;
  554.  
  555. GrHwConfiguration glbHWConfig;
  556. int glbCurrentBoard=0;
  557.  
  558. /*
  559.  * Select the Voodoo board to use when creating
  560.  * a new context.
  561.  */
  562.  
  563. GLboolean APIENTRY fxMesaSelectCurrentBoard(int n)
  564. {
  565.   fxQueryHardware();
  566.  
  567.   if((n<0) || (n>=glbHWConfig.num_sst))
  568.     return GL_FALSE;
  569.  
  570.   glbCurrentBoard=n;
  571.  
  572.   return GL_TRUE;
  573. }
  574.  
  575.  
  576. fxMesaContext APIENTRY fxMesaGetCurrentContext(void)
  577. {
  578.   return fxMesaCurrentCtx;
  579. }
  580.  
  581.  
  582. void APIENTRY fxMesaSetNearFar(GLfloat n, GLfloat f)
  583. {
  584.   if(fxMesaCurrentCtx)
  585.     fxDDSetNearFar(fxMesaCurrentCtx->glCtx,n,f);
  586. }
  587.  
  588.  
  589. /*
  590.  * The extension GL_FXMESA_global_texture_lod_bias
  591.  */
  592. void APIENTRY glGlobalTextureLODBiasFXMESA(GLfloat biasVal)
  593. {
  594.   grTexLodBiasValue(GR_TMU0,biasVal);
  595.  
  596.   if(fxMesaCurrentCtx->haveTwoTMUs)
  597.     grTexLodBiasValue(GR_TMU1,biasVal);
  598. }
  599.  
  600.  
  601. /*
  602.  * The 3Dfx Global Palette extension for GLQuake.
  603.  * More a trick than a real extesion, use the shared global
  604.  * palette extension. 
  605.  */
  606. void APIENTRY gl3DfxSetPaletteEXT(GLuint *pal)
  607. {
  608. #if defined(DEBUG_FXMESA)
  609.   int i;
  610.  
  611.   fprintf(stderr,"fxmesa: gl3DfxSetPaletteEXT()\n");
  612.  
  613.   for(i=0;i<256;i++)
  614.     fprintf(stderr,"%x\n",pal[i]);
  615. #endif
  616.  
  617.   if(fxMesaCurrentCtx) {
  618.     fxMesaCurrentCtx->haveGlobalPaletteTexture=1;
  619.  
  620.     grTexDownloadTable(GR_TMU0,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
  621.  
  622.     if(fxMesaCurrentCtx->haveTwoTMUs)
  623.       grTexDownloadTable(GR_TMU1,GR_TEXTABLE_PALETTE,(GuTexPalette *)pal);
  624.   }
  625. }
  626.  
  627.  
  628. static GrScreenResolution_t fxBestResolution(int width, int height, int aux)
  629. {
  630.   static int resolutions[][5]={ 
  631.     { 512, 384, GR_RESOLUTION_512x384, 2, 2 },
  632.     { 640, 400, GR_RESOLUTION_640x400, 2, 2 },
  633.     { 640, 480, GR_RESOLUTION_640x480, 2, 2 },
  634.     { 800, 600, GR_RESOLUTION_800x600, 4, 2 },
  635.     { 960, 720, GR_RESOLUTION_960x720, 6, 4 }
  636. #ifdef GR_RESOLUTION_1024x768
  637.     ,{ 1024, 768, GR_RESOLUTION_1024x768, 8, 4 }
  638. #endif
  639.   };
  640.   int NUM_RESOLUTIONS = sizeof(resolutions) / (sizeof(int)*5);
  641.   int i,fbmem;
  642.   GrScreenResolution_t lastvalidres;
  643.  
  644.   fxQueryHardware();
  645.  
  646.   if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
  647.     fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam;
  648.  
  649.     if(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect)
  650.       fbmem*=2;
  651.   } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
  652.     fbmem=glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam;
  653.   else
  654.     fbmem=2;
  655.  
  656.   /* A work around for BZFlag */
  657.  
  658.   if((width==1) && (height==1)) {
  659.     width=640;
  660.     height=480;
  661.   }
  662.  
  663.   for(i=0;i<NUM_RESOLUTIONS;i++)
  664.     if(resolutions[i][4-aux]<=fbmem) {
  665.       if((width<=resolutions[i][0]) && (height<=resolutions[i][1]))
  666.     return resolutions[i][2];
  667.  
  668.       lastvalidres=resolutions[i][2];
  669.     }
  670.  
  671.   return lastvalidres;
  672. }
  673.  
  674.  
  675. fxMesaContext APIENTRY fxMesaCreateBestContext(GLuint win,GLint width, GLint height,
  676.                            const GLint attribList[])
  677. {
  678.   GrScreenRefresh_t refresh;
  679.   int i;
  680.   int res,aux;
  681.   refresh=GR_REFRESH_75Hz;
  682.  
  683.   if(getenv("SST_SCREENREFRESH")) {
  684.     if(!strcmp(getenv("SST_SCREENREFRESH"),"60"))
  685.       refresh=GR_REFRESH_60Hz;
  686.     if(!strcmp(getenv("SST_SCREENREFRESH"),"70"))
  687.       refresh=GR_REFRESH_70Hz;
  688.     if(!strcmp(getenv("SST_SCREENREFRESH"),"72"))
  689.       refresh=GR_REFRESH_72Hz;
  690.     if(!strcmp(getenv("SST_SCREENREFRESH"),"75"))
  691.       refresh=GR_REFRESH_75Hz;
  692.     if(!strcmp(getenv("SST_SCREENREFRESH"),"80"))
  693.       refresh=GR_REFRESH_80Hz;
  694.     if(!strcmp(getenv("SST_SCREENREFRESH"),"85"))
  695.       refresh=GR_REFRESH_85Hz;
  696.     if(!strcmp(getenv("SST_SCREENREFRESH"),"90"))
  697.       refresh=GR_REFRESH_90Hz;
  698.     if(!strcmp(getenv("SST_SCREENREFRESH"),"100"))
  699.       refresh=GR_REFRESH_100Hz;
  700.     if(!strcmp(getenv("SST_SCREENREFRESH"),"120"))
  701.       refresh=GR_REFRESH_120Hz;
  702.   }
  703.  
  704.   aux=0;
  705.   for(i=0;attribList[i]!=FXMESA_NONE;i++)
  706.     if((attribList[i]==FXMESA_ALPHA_SIZE) ||
  707.        (attribList[i]==FXMESA_DEPTH_SIZE)) {
  708.       if(attribList[++i]>0) {
  709.     aux=1;
  710.     break;
  711.       }
  712.     }
  713.  
  714.   res=fxBestResolution(width,height,aux);
  715.  
  716.   return fxMesaCreateContext(win,res,refresh,attribList);
  717. }
  718.  
  719.  
  720. /*
  721.  * Create a new FX/Mesa context and return a handle to it.
  722.  */
  723. fxMesaContext APIENTRY fxMesaCreateContext(GLuint win,GrScreenResolution_t res,
  724.                        GrScreenRefresh_t ref,
  725.                        const GLint attribList[])
  726. {
  727.   fxMesaContext fxMesa;
  728.   int i,type;
  729.   int aux;
  730.   GLboolean doubleBuffer=GL_FALSE;
  731.   GLboolean alphaBuffer=GL_FALSE;
  732.   GLboolean verbose=GL_FALSE;
  733.   GLint depthSize=0;
  734.   GLint stencilSize=0;
  735.   GLint accumSize=0;
  736.  
  737. #if defined(DEBUG_FXMESA)
  738.   fprintf(stderr,"fxmesa: fxMesaCreateContext() Start\n");
  739. #endif
  740.  
  741.   if(getenv("MESA_FX_INFO"))
  742.     verbose=GL_TRUE;
  743.  
  744.   aux=0;
  745.   i=0;
  746.   while(attribList[i]!=FXMESA_NONE) {
  747.     switch (attribList[i]) {
  748.     case FXMESA_DOUBLEBUFFER:
  749.       doubleBuffer=GL_TRUE;
  750.       break;
  751.     case FXMESA_ALPHA_SIZE:
  752.       i++;
  753.       alphaBuffer=attribList[i]>0;
  754.       if(alphaBuffer)
  755.     aux=1;
  756.       break;
  757.     case FXMESA_DEPTH_SIZE:
  758.       i++;
  759.       depthSize=attribList[i];
  760.       if(depthSize)
  761.     aux=1;
  762.       break;
  763.     case FXMESA_STENCIL_SIZE:
  764.       i++;
  765.       stencilSize=attribList[i];
  766.       break;
  767.     case FXMESA_ACCUM_SIZE:
  768.       i++;
  769.       accumSize=attribList[i];
  770.       break;
  771.     default:
  772. #if defined(DEBUG_FXMESA)
  773.       fprintf(stderr,"fxmesa: fxMesaCreateContext() End (defualt)\n");
  774. #endif
  775.       return NULL;
  776.     }
  777.     i++;
  778.   }
  779.  
  780.   /* A workaround for Linux GLQuake */
  781.   if(depthSize && alphaBuffer)
  782.     alphaBuffer=0;
  783.  
  784.   if(verbose)
  785.     fprintf(stderr,"Mesa fx Voodoo Device Driver v0.29\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  786.  
  787.   if((type=fxQueryHardware()) >= 0) {
  788.     if(type==GR_SSTTYPE_VOODOO)
  789.       win=0;
  790.  
  791.     grSstSelect(glbCurrentBoard);
  792.  
  793.     if(!grSstWinOpen((FxU32)win,res,ref,
  794.                      GR_COLORFORMAT_ABGR,GR_ORIGIN_LOWER_LEFT,2,aux)) {
  795. #if defined(DEBUG_FXMESA)
  796.       fprintf(stderr,"fxmesa: fxMesaCreateContext() End (grSstWinOpen)\n");
  797. #endif
  798.       return NULL;
  799.     }
  800.  
  801.     if(verbose)
  802.       fprintf(stderr,"Glide screen size: %dx%d\n",
  803.           (int)grSstScreenWidth(),(int)grSstScreenHeight());
  804.   } else {
  805.     fprintf(stderr,"fx Driver: ERROR no Voodoo1/2 Graphics or Voodoo Rush !\n");
  806.     return NULL;
  807.   }
  808.  
  809.   fxMesa=(fxMesaContext)malloc(sizeof(struct tfxMesaContext));
  810.   if(!fxMesa) {
  811. #if defined(DEBUG_FXMESA)
  812.     fprintf(stderr,"fxmesa: fxMesaCreateContext() End (malloc)\n");
  813. #endif
  814.     return NULL;
  815.   }
  816.  
  817.   fxMesa->board=glbCurrentBoard;
  818.   fxMesa->width=grSstScreenWidth();
  819.   fxMesa->height=grSstScreenHeight();
  820.  
  821.   fxMesa->verbose=verbose;
  822.  
  823.   if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO)
  824.     fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx > 1);
  825.   else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96)
  826.     fxMesa->haveTwoTMUs=(glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx > 1);
  827.   else
  828.     fxMesa->haveTwoTMUs=GL_FALSE;
  829.  
  830.   fxMesa->haveDoubleBuffer=doubleBuffer;
  831.   fxMesa->haveAlphaBuffer=alphaBuffer;
  832.   fxMesa->haveGlobalPaletteTexture=GL_FALSE;
  833.  
  834.   if(getenv("FX_GLIDE_SWAPINTERVAL"))
  835.     fxMesa->swapInterval=atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
  836.   else
  837.     fxMesa->swapInterval=1;
  838.  
  839.   if(getenv("MESA_FX_SWAP_PENDING"))
  840.     fxMesa->maxPendingSwapBuffers=atoi(getenv("MESA_FX_SWAP_PENDING"));
  841.   else
  842.     fxMesa->maxPendingSwapBuffers=2;
  843.  
  844.   fxMesa->color=FXCOLOR(255,255,255,255);
  845.   fxMesa->clearC=0;
  846.   fxMesa->clearA=0;
  847.  
  848.   fxMesa->stats.swapBuffer=0;
  849.   fxMesa->stats.reqTexUpload=0;
  850.   fxMesa->stats.texUpload=0;
  851.   fxMesa->stats.memTexUpload=0;
  852.  
  853.   fxMesa->tmuSrc=FX_TMU_NONE;
  854.   fxMesa->lastUnitsMode=FX_UM_NONE;
  855.   fxTMInit(fxMesa);
  856.  
  857.   grColorMask(FXTRUE,alphaBuffer ? FXTRUE : FXFALSE);
  858.   if(doubleBuffer) {
  859.     fxMesa->currentFB=GR_BUFFER_BACKBUFFER;
  860.     grRenderBuffer(GR_BUFFER_BACKBUFFER);
  861.   } else {
  862.     fxMesa->currentFB=GR_BUFFER_FRONTBUFFER;
  863.     grRenderBuffer(GR_BUFFER_FRONTBUFFER);
  864.   }
  865.  
  866.   if(depthSize) {
  867.     grDepthMask(FXTRUE);
  868.     grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
  869.   }
  870.  
  871.   grLfbWriteColorFormat(GR_COLORFORMAT_ABGR);
  872.  
  873.   fxMesa->glVis=gl_create_visual(GL_TRUE,     /* RGB mode */
  874.                  alphaBuffer,
  875.                  doubleBuffer,
  876.                  GL_FALSE,    /* stereo */
  877.                  depthSize,   /* depth_size */
  878.                  stencilSize, /* stencil_size */
  879.                  accumSize,   /* accum_size */
  880.                  0,           /* index bits */
  881.                  5,6,5,0);    /* RGBA bits */
  882.  
  883.   fxMesa->glCtx=gl_create_context(fxMesa->glVis,
  884.                   NULL,  /* share list context */
  885.                   (void *) fxMesa, GL_TRUE);
  886.  
  887.   fxMesa->glBuffer=gl_create_framebuffer(fxMesa->glVis);
  888.  
  889.   fxSetupDDPointers(fxMesa->glCtx);
  890.  
  891.   fxDDSetNearFar(fxMesa->glCtx,1.0,100.0);
  892.  
  893.   grGlideGetState(&fxMesa->state);
  894.  
  895.   glbTotNumCtx++;
  896.  
  897. #if defined(DEBUG_FXMESA)
  898.   fprintf(stderr,"fxmesa: fxMesaCreateContext() End\n");
  899. #endif
  900.  
  901.   return fxMesa;
  902. }
  903.  
  904.  
  905. /*
  906.  * Function to set the new window size in the context (mainly for the Voodoo Rush)
  907.  */
  908. void APIENTRY fxMesaUpdateScreenSize(fxMesaContext fxMesa)
  909. {
  910.   fxMesa->width=grSstScreenWidth();
  911.   fxMesa->height=grSstScreenHeight();
  912. }
  913.  
  914.  
  915. /*
  916.  * Destroy the given FX/Mesa context.
  917.  */
  918. void APIENTRY fxMesaDestroyContext(fxMesaContext fxMesa)
  919. {
  920. #if defined(DEBUG_FXMESA)
  921.   fprintf(stderr,"fxmesa: fxMesaDestroyContext()\n");
  922. #endif
  923.  
  924.   if(fxMesa) {
  925.     gl_destroy_visual(fxMesa->glVis);
  926.     gl_destroy_context(fxMesa->glCtx);
  927.     gl_destroy_framebuffer(fxMesa->glBuffer);
  928.  
  929.     glbTotNumCtx--;
  930.  
  931.     fxCloseHardware();
  932.  
  933.     if(fxMesa->verbose) {
  934.       fprintf(stderr,"Misc Stats:\n");
  935.       fprintf(stderr,"  # swap buffer: %u\n",fxMesa->stats.swapBuffer);
  936.  
  937.       if(!fxMesa->stats.swapBuffer)
  938.     fxMesa->stats.swapBuffer=1;
  939.  
  940.       fprintf(stderr,"Textures Stats:\n");
  941.       fprintf(stderr,"  Free texture memory on TMU0: %d:\n",fxMesa->freeTexMem[FX_TMU0]);
  942.       if(fxMesa->haveTwoTMUs)
  943.     fprintf(stderr,"  Free texture memory on TMU1: %d:\n",fxMesa->freeTexMem[FX_TMU1]);
  944.       fprintf(stderr,"  # request to TMM to upload a texture objects: %u\n",
  945.           fxMesa->stats.reqTexUpload);
  946.       fprintf(stderr,"  # request to TMM to upload a texture objects per swapbuffer: %.2f\n",
  947.           fxMesa->stats.reqTexUpload/(float)fxMesa->stats.swapBuffer);
  948.       fprintf(stderr,"  # texture objects uploaded: %u\n",
  949.           fxMesa->stats.texUpload);
  950.       fprintf(stderr,"  # texture objects uploaded per swapbuffer: %.2f\n",
  951.           fxMesa->stats.texUpload/(float)fxMesa->stats.swapBuffer);
  952.       fprintf(stderr,"  # MBs uploaded to texture memory: %.2f\n",
  953.           fxMesa->stats.memTexUpload/(float)(1<<20));
  954.       fprintf(stderr,"  # MBs uploaded to texture memory per swapbuffer: %.2f\n",
  955.           (fxMesa->stats.memTexUpload/(float)fxMesa->stats.swapBuffer)/(float)(1<<20));
  956.     }
  957.  
  958.     fxTMClose(fxMesa);
  959.  
  960.     free(fxMesa);
  961.   }
  962.  
  963.   if(fxMesa==fxMesaCurrentCtx)
  964.     fxMesaCurrentCtx=NULL;
  965. }
  966.  
  967.  
  968. /*
  969.  * Make the specified FX/Mesa context the current one.
  970.  */
  971. void APIENTRY fxMesaMakeCurrent(fxMesaContext fxMesa)
  972. {
  973. #if defined(DEBUG_FXMESA)
  974.   fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) Start\n");
  975. #endif
  976.  
  977.   if(!fxMesa) {
  978.     gl_make_current(NULL,NULL);
  979.     fxMesaCurrentCtx=NULL;
  980.  
  981. #if defined(DEBUG_FXMESA)
  982.     fprintf(stderr,"fxmesa: fxMesaMakeCurrent(NULL) End\n");
  983. #endif
  984.  
  985.     return;
  986.   }
  987.  
  988.   if(fxMesaCurrentCtx==fxMesa) {
  989. #if defined(DEBUG_FXMESA)
  990.     fprintf(stderr,"fxmesa: fxMesaMakeCurrent(fxMesaCurrentCtx==fxMesa) End\n");
  991. #endif
  992.  
  993.     return;
  994.   }
  995.  
  996.  
  997.   if(fxMesaCurrentCtx)
  998.     grGlideGetState(&fxMesaCurrentCtx->state);
  999.  
  1000.   fxMesaCurrentCtx=fxMesa;
  1001.  
  1002.   grSstSelect(fxMesa->board);
  1003.   grGlideSetState(&fxMesa->state);
  1004.  
  1005.   gl_make_current(fxMesa->glCtx,fxMesa->glBuffer);
  1006.  
  1007.   fxSetupDDPointers(fxMesa->glCtx);
  1008.  
  1009.   /* The first time we call MakeCurrent we set the initial viewport size */
  1010.   if(fxMesa->glCtx->Viewport.Width==0)
  1011.     gl_Viewport(fxMesa->glCtx,0,0,fxMesa->width,fxMesa->height);
  1012.  
  1013. #if defined(DEBUG_FXMESA)
  1014.   fprintf(stderr,"fxmesa: fxMesaMakeCurrent(...) End\n");
  1015. #endif
  1016. }
  1017.  
  1018.  
  1019. /*
  1020.  * Swap front/back buffers for current context if double buffered.
  1021.  */
  1022. void APIENTRY fxMesaSwapBuffers(void)
  1023. {
  1024. #if defined(DEBUG_FXMESA)
  1025.   fprintf(stderr,"fxmesa: ------------------------------- fxMesaSwapBuffers() -------------------------------\n");
  1026. #endif
  1027.  
  1028.   if(fxMesaCurrentCtx)
  1029.     if(fxMesaCurrentCtx->haveDoubleBuffer) {
  1030.       grBufferSwap(fxMesaCurrentCtx->swapInterval);
  1031.  
  1032.       /*
  1033.        * Don't allow swap buffer commands to build up!
  1034.        */
  1035.       while(grBufferNumPending()>fxMesaCurrentCtx->maxPendingSwapBuffers);
  1036.  
  1037.       fxMesaCurrentCtx->stats.swapBuffer++;
  1038.     }
  1039. }
  1040.  
  1041.  
  1042. #if defined(__WIN32__)
  1043. static int cleangraphics(void)
  1044. {
  1045.   glbTotNumCtx=1;
  1046.   fxMesaDestroyContext(fxMesaCurrentCtx);
  1047.  
  1048.   return 0;
  1049. }
  1050. #elif defined(__linux__)
  1051. static void cleangraphics(void)
  1052. {
  1053.   glbTotNumCtx=1;
  1054.   fxMesaDestroyContext(fxMesaCurrentCtx);
  1055. }
  1056.  
  1057. static void cleangraphics_handler(int s)
  1058. {
  1059.   fprintf(stderr,"fxmesa: Received a not handled signal %d\n",s);
  1060.  
  1061.   cleangraphics();
  1062.   exit(-1);
  1063. }
  1064. #endif
  1065.  
  1066.  
  1067. /*
  1068.  * Query 3Dfx hardware presence/kind
  1069.  */
  1070. int APIENTRY fxQueryHardware(void)
  1071. {
  1072. #if defined(DEBUG_FXMESA)
  1073.   fprintf(stderr,"fxmesa: fxQueryHardware() Start\n");
  1074. #endif
  1075.  
  1076.   if(!glbGlideInitialized) {
  1077.     grGlideInit();
  1078.     if(grSstQueryHardware(&glbHWConfig)) {
  1079.       grSstSelect(glbCurrentBoard);
  1080.       glb3DfxPresent=1;
  1081.  
  1082.       if(getenv("MESA_FX_INFO")) {
  1083.     char buf[80];
  1084.             
  1085.     grGlideGetVersion(buf);
  1086.     fprintf(stderr,"Using Glide V%s\n",buf);
  1087.     fprintf(stderr,"Number of boards: %d\n",glbHWConfig.num_sst);
  1088.  
  1089.     if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
  1090.       fprintf(stderr,"Framebuffer RAM: %d\n",
  1091.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect ?
  1092.           (glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam*2) :
  1093.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.fbRam);
  1094.       fprintf(stderr,"Number of TMUs: %d\n",
  1095.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.nTexelfx);
  1096.       fprintf(stderr,"SLI detected: %d\n",
  1097.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig.sliDetect);
  1098.     } else if(glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96) {
  1099.       fprintf(stderr,"Framebuffer RAM: %d\n",
  1100.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.fbRam);
  1101.       fprintf(stderr,"Number of TMUs: %d\n",
  1102.           glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config.nTexelfx);
  1103.     }
  1104.  
  1105.       }
  1106.     } else
  1107.       glb3DfxPresent=0;
  1108.  
  1109.     glbGlideInitialized=1;
  1110.  
  1111. #if defined(__WIN32__)
  1112.     onexit((_onexit_t)cleangraphics);
  1113. #elif defined(__linux__)
  1114.     atexit(cleangraphics);
  1115.  
  1116.     signal(SIGINT,cleangraphics_handler);
  1117.     signal(SIGHUP,cleangraphics_handler);
  1118.     signal(SIGPIPE,cleangraphics_handler);
  1119.     signal(SIGFPE,cleangraphics_handler);
  1120.     signal(SIGBUS,cleangraphics_handler);
  1121.     signal(SIGILL,cleangraphics_handler);
  1122.     signal(SIGSEGV,cleangraphics_handler);
  1123.     signal(SIGTERM,cleangraphics_handler);
  1124. #endif
  1125.   }
  1126.  
  1127.   if(!glb3DfxPresent) {
  1128. #if defined(DEBUG_FXMESA)
  1129.     fprintf(stderr,"fxmesa: fxQueryHardware() End (-1)\n");
  1130. #endif
  1131.     return(-1);
  1132.   }
  1133.  
  1134. #if defined(DEBUG_FXMESA)
  1135.   fprintf(stderr,"fxmesa: fxQueryHardware() End (voodooo)\n");
  1136. #endif
  1137.   return(glbHWConfig.SSTs[glbCurrentBoard].type);
  1138. }
  1139.  
  1140.  
  1141. /*
  1142.  * Shutdown Glide library
  1143.  */
  1144. void APIENTRY fxCloseHardware(void)
  1145. {
  1146.   if(glbGlideInitialized) {
  1147.     if(getenv("MESA_FX_INFO")) {
  1148.       GrSstPerfStats_t        st;
  1149.  
  1150.       grSstPerfStats(&st);
  1151.       fprintf(stderr,"Pixels Stats:\n");
  1152.       fprintf(stderr,"  # pixels processed (minus buffer clears): %u\n",(unsigned)st.pixelsIn);
  1153.       fprintf(stderr,"  # pixels not drawn due to chroma key test failure: %u\n",(unsigned)st.chromaFail);
  1154.       fprintf(stderr,"  # pixels not drawn due to depth test failure: %u\n",(unsigned)st.zFuncFail);
  1155.       fprintf(stderr,"  # pixels not drawn due to alpha test failure: %u\n",(unsigned)st.aFuncFail);
  1156.       fprintf(stderr,"  # pixels drawn (including buffer clears and LFB writes): %u\n",(unsigned)st.pixelsOut);
  1157.     }
  1158.  
  1159.     if(glbTotNumCtx==0) {
  1160.       grGlideShutdown();
  1161.       glbGlideInitialized=0;
  1162.     }
  1163.   }
  1164. }
  1165.  
  1166.  
  1167. #else
  1168.  
  1169.  
  1170. /*
  1171.  * Need this to provide at least one external definition.
  1172.  */
  1173.  
  1174. int gl_fx_dummy_function_api(void)
  1175. {
  1176.   return 0;
  1177. }
  1178.  
  1179. #endif  /* FX */
  1180.